#ifndef IDATABASE_H_
#define IDATABASE_H_


//boost headers
#include <boost/any.hpp>

//std headers
#include <vector>
#include <string>
#include <utility>


namespace DB{


	//! Datapair
	/*!
		typedef na std::vector<std::pair<std::string,boost::any> >
	*/
	typedef std::vector<std::pair<std::string,boost::any> > Datapair;

	//! DataPairWrapper
	/*!
		Wrapper na DataPair ktory umoznuje jednoduche ziskanie
		dat podla ich nazvu. Umoznuje ziskat but len prve data
		z vsetkych ,alebo aj vsetky ako kolekciu
	*/
	class DataPairWrapper
	{
		public:
			DataPairWrapper(std::vector<Datapair> &data) : myData(data)	{}

			
			//! GetOne (public )
			/*!
				Ziska len jeden (prvy) udaj
				\param std::string dataName - nazov udaju
				\return T typ udaju 
			*/
			template<typename T> T GetOne(std::string dataName)
			{
				T _result = Get<T>(dataName)[0];
				return _result;
			}
			

			//! Get (public )
			/*!
				Ziska vsetky udaje 
				\param std::string dataName nazov udaju
				\return std::vector<T> kolekcia udajov
			*/
			template<typename T> std::vector<T> Get(std::string dataName)
			{
				std::vector<T> _result;

				for(std::size_t i=0; i < myData.size(); ++i)
				{
					for(std::size_t x=0; x < myData[i].size(); ++x)
					{
						if(myData[i][x].first == dataName)
						{
							_result.push_back(boost::any_cast<T>(myData[i][x].second));
						}
					}
				}

				return _result;
			}
		private:
			std::vector<Datapair> &myData;
	};




//! IDatabase 
/*!
	IDatabase je abstraktnu triedu ktora sluzi
	ako Interface pre vsetky triedy urcene na
	komunikaciu s tym ktorym typom Databazi.
*/
class IDatabase
{
	public:

		virtual ~IDatabase() {}

		//! Insert (public )
		/*!
			Sluzi na vkladanie dat do databazy pre danu tabulku
			\param std::string theTableName nazov tabulky v DB
			\param std::vector<boost::any> theData data na poslanie, pricom par
					je tvoreny nazvom stlpca a data iduce do daneho stlpca
			\return bool true ak data sa ulozili do tabulky v poriadku ,false inak
		*/
		virtual bool Insert(std::string theTableName,std::vector<std::pair<std::string,boost::any> > &theData) = 0;


		//! Insert (public )
		/*!
			Sluzi na vykonanie insertu nad databazou pricom samotny insert
			je napisany uzivatelom.
			\param std::string theSQLstr  SQL vyraz
			\return bool true ak insert bol uspesny, false inak
		*/
		virtual bool Insert(std::string &theSQLstr) = 0;


		//! Select (public )
		/*!
			Sluzi na vykonanie SQL query nad databazou
			\param std::string & theSQLquery samotna query
			\param std::vector<std::pair<std::string,boost::any> > &theData data ziskane pomocou query
			\return bool true ak uspesne query, false inak
		*/
		virtual bool Select(std::string &theSQLquery,std::vector<Datapair> &theData) = 0;



		//! Update (public )
		/*!
			Sluzi na aktualizaciu hodnot v tabulke
			\param std::string theTableName
			\param std::vector<std::pair<std::string,boost::any> > & newData
			\param std::vector<std::pair<std::string,boost::any> > & oldData
			\return bool
		*/
		virtual bool Update(std::string theTableName,Datapair &newData, Datapair &oldData)= 0;



		//! Update (public )
		/*!
			Popis.... 
			\param std::string & theSQL
			\return bool
		*/
		virtual bool Update(std::string &theSQL) = 0;


		//! Delete (public )
		/*!
			Popis.... 
			\param std::string & theSQL
			\return bool
		*/
		virtual bool Delete(std::string &theSQL) = 0;

}; //end of IDatabase

}//end of DB namespace

#endif //IDATABASE_H_